package com.liyu.iblog.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.liyu.iblog.dao.GenericDao;
import com.liyu.iblog.domain.DomainObject;

public class GenericDaoJpa<T extends DomainObject> implements GenericDao<T> {

    private Class<T> type;
    
    protected EntityManagerFactory emf;
    
    @Autowired
    @Qualifier("entityManagerFactory")
    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        this.emf = entityManagerFactory;
    }
    
    public GenericDaoJpa(Class<T> type) {
        super();
        this.type = type;
    }
    
    @Override
    public T get(Object id) {
        if (id == null)
            return null;
        else {
            EntityManager em = emf.createEntityManager();
            T obj = null;
            try {
                obj = em.find(type, id);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                em.close();
            }
            return obj;
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> getAll() {
        EntityManager em = emf.createEntityManager();
        List<T> list = null;
        try {
            Query query = em.createQuery(
                    "select o from " + type.getName() + " o");
            list =  query.getResultList();
            //must call this in google app engine, otherwise not work
            list.size();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            em.close();
        }
        return list;
    }

    @Override
    public void save(T object) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.persist(object);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //not support rollback
//            tx.rollback();
        } finally {
            em.close();
        }
    }

    @Override
    public void delete(Object key) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            T t = em.find(type, key);
            em.remove(t);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
//            tx.rollback();
        } finally {
            em.close();
        }
    }

}
